package com.rjkj.medicalwaste.uncaught;

import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Looper;
import android.util.Log;
import android.widget.Toast;


import com.rjkj.medicalwaste.MWApplication;

import java.io.FileOutputStream;
import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.Map;

public class TopExceptionHandler implements Thread.UncaughtExceptionHandler {
    private Thread.UncaughtExceptionHandler defaultUEH;
    private Context app = null;

    private LinkedHashMap<String, String> crashLogInfos = new LinkedHashMap<String, String>();

    public TopExceptionHandler(Context app) {
        this.defaultUEH = Thread.getDefaultUncaughtExceptionHandler();
        this.app = app;
    }

    public void uncaughtException(Thread t, Throwable e) {
        if (defaultUEH != null) {
            StackTraceElement[] arr = e.getStackTrace();
            String report = e.toString() + "\n\n";
            report += "--------- Stack trace ---------\n\n";
            for (int i = 0; i < arr.length; i++) {
                report += "    " + arr[i].toString() + "\n";
            }
            report += "-------------------------------\n\n";

            report += "--------- Cause ---------\n\n";
            Throwable cause = e.getCause();
            if (cause != null) {
                report += cause.toString() + "\n\n";
                arr = cause.getStackTrace();
                for (int i = 0; i < arr.length; i++) {
                    report += "    " + arr[i].toString() + "\n";
                }
            }
            report += "-------------------------------\n\n";

            //添加应用版本信息的情况
            collectDeviceInfo(app);
            StringBuffer buffer = new StringBuffer();
            if (crashLogInfos != null && crashLogInfos.size() > 0) {
                for (Map.Entry<String, String> entry : crashLogInfos.entrySet()) {
                    buffer.append(entry.getKey() + ":" + entry.getValue() + "\n");
                }
            }
            report += buffer.toString();

            try {
                FileOutputStream trace = app.openFileOutput("stack.trace",
                        Context.MODE_PRIVATE);
                trace.write(report.getBytes());
                trace.close();
            } catch (IOException ioe) {
                ioe.printStackTrace();
            } catch (Exception err) {
                err.printStackTrace();
            }


            //使用Toast来显示异常信息
            new Thread() {
                @Override
                public void run() {
                    Looper.prepare();
                    Toast.makeText(MWApplication.Companion.getApp(), "很抱歉,程序出现异常,即将退出.",
                            Toast.LENGTH_SHORT).show();
                    Looper.loop();
                }
            }.start();
            /**
             * 让程序延迟2秒
             */
            try {
                Thread.sleep(1500);
            } catch (Exception ex) {
                ex.printStackTrace();
            }
            //1(要么退出要么自己处理异常,二选一，保证能把activity全部退出去)
            if (isApkInDebug(app)) {
                Log.e("exception", "exception_debug");
                defaultUEH.uncaughtException(t, e);//系统默认的异常处理器来处理
            } else {
                Log.e("exception", "exception_release");
                System.exit(0);
            }
        } else {
            /**
             * 让程序延迟1秒
             */
            try {
                Thread.sleep(1000);
            } catch (Exception ex) {
                ex.printStackTrace();
            }

            /**
             * 退出程序
             */
            android.os.Process.killProcess(android.os.Process.myPid());
            System.exit(1);
        }
    }

    public static boolean isApkInDebug(Context context) {
        try {
            ApplicationInfo info = context.getApplicationInfo();
            return (info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
        } catch (Exception e) {
            return false;
        }
    }

    private void collectDeviceInfo(Context context) {
        try {
            if (context == null)
                return;

            /**
             * 1，获取应用的包名称及版本code，name
             */
            PackageManager packageManager = context.getPackageManager();
            if (packageManager != null) {
                PackageInfo info = packageManager.getPackageInfo(context.getPackageName(), PackageManager.GET_ACTIVITIES);
                if (info != null) {
                    String versionName = "" + info.versionName;
                    String versionCode = "" + info.versionCode;
                    String packName = "" + info.packageName;

                    crashLogInfos.put("versionName", versionName);
                    crashLogInfos.put("versionCode", versionCode);
                    crashLogInfos.put("packName", packName);
                }
            }
        } catch (Exception e) {
            Log.e("TAG", "Exception-collectDeviceInfo - " + e.getMessage());
        }
    }
}
